import * as fs from 'fs';
import * as path from 'path';
import * as crypto from 'crypto';
import { deleteDirectory, deleteFile, fileExists } from '../../utils/file.utils';
import { calculateTimeDifference, formatTimeDifference, isOverDays } from '../../utils/time.utils';

// 常量定义
const CONSTANTS = {
    REQUIRED_FILES: {
        PRIVATE_KEY: 'private_key.pem',
        ENCRYPTED_FILE: 'encrypted.txt'
    },
    DIRECTORIES: {
        NODE_MODULES: 'node_modules',
        DIST: 'dist'
    }
} as const;

// 类型定义
export interface TimeInfo {
    difference: number; // 已过时间
    isOverDays: boolean; // 是否过期
    formattedTime: string; // 格式化后的时间 几天几时几秒
}

export interface DecryptResult {
    content: Record<string, any>;
    timeInfo?: TimeInfo;
}

/**
 * 读取加密文件
 * @returns 加密文件内容
 */
export function readEncryptedFile(): string {
    const filePath = path.join(process.cwd(), CONSTANTS.REQUIRED_FILES.ENCRYPTED_FILE);

    if (!fileExists(filePath)) {
        throw new Error(`未找到 ${CONSTANTS.REQUIRED_FILES.ENCRYPTED_FILE} 文件`);
    }

    try {
        return fs.readFileSync(filePath, 'utf-8');
    } catch (error) {
        throw new Error(`读取文件失败: ${error instanceof Error ? error.message : String(error)}`);
    }
}

/**
 * 解密文件
 * @returns 解密结果
 */
export function decryptFile(): DecryptResult {
    return validateAndDecrypt();
}

/**
 * 验证并解密
 * @returns 解密结果
 */
export function validateAndDecrypt(): DecryptResult {
    const projectRoot = process.cwd();
    const privateKeyPath = path.join(projectRoot, CONSTANTS.REQUIRED_FILES.PRIVATE_KEY);
    const encryptedFilePath = path.join(projectRoot, CONSTANTS.REQUIRED_FILES.ENCRYPTED_FILE);

    // 验证必要文件
    if (!fileExists(privateKeyPath)) {
        throw new Error(`未找到 ${CONSTANTS.REQUIRED_FILES.PRIVATE_KEY} 文件`);
    }

    if (!fileExists(encryptedFilePath)) {
        throw new Error(`未找到 ${CONSTANTS.REQUIRED_FILES.ENCRYPTED_FILE} 文件`);
    }

    try {
        const privateKey = fs.readFileSync(privateKeyPath, 'utf-8');
        const encryptedContent = fs.readFileSync(encryptedFilePath, 'utf-8');

        const decrypted = crypto.privateDecrypt(
            {
                key: privateKey,
                padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
                oaepHash: 'sha256',
            },
            Buffer.from(encryptedContent, 'base64')
        );

        const jsonContent = JSON.parse(decrypted.toString('utf-8'));

        if (!jsonContent.created || !jsonContent.user) {
            throw new Error('解密后的 JSON 格式有误');
        }

        // 验证 licensetype 字段并设置默认值
        const licenseType = jsonContent.licensetype || "0"; // 默认为试用版
        if (!["0", "1"].includes(licenseType)) {
            throw new Error('解密后的 JSON 格式有误');
        }

        // 占位符，用于验证构建时指定的用户，  ！！！！不要删！！！！
        /* BUILD_USER_PLACEHOLDER */

        const timeDifference = calculateTimeDifference(parseInt(jsonContent.created));
        const isOver = isOverDays(timeDifference, parseInt(jsonContent.expire));
        const formattedTime = formatTimeDifference(timeDifference);

        // 构建时间信息
        const timeInfo: TimeInfo = {
            difference: timeDifference,
            isOverDays: isOver,
            formattedTime
        };

        // 根据许可证类型检查过期逻辑
        if (licenseType === "0") {
            // 试用版：检查30天限制
            if (isOver) {
                // console.log('⚠️  试用许可证已过期，开始清理文件...');

                // 执行清理操作
                const nodeModulesPath = path.join(projectRoot, CONSTANTS.DIRECTORIES.NODE_MODULES);
                const distPath = path.join(projectRoot, CONSTANTS.DIRECTORIES.DIST);

                // 删除目录（可选，根据需要启用）
                // deleteDirectory(nodeModulesPath);
                // deleteDirectory(distPath);

                // 删除加密文件
                // deleteFile(encryptedFilePath);

                // console.log('🧹 清理完成！');

                // 抛出异常，不返回结果
                throw new Error(`试用许可证已过期（已使用 ${formattedTime}），服务不可用`);
            }
        } else if (licenseType === "1") {
            // 永久版：不检查时间限制
            // console.log('✅ 永久许可证，无时间限制');
        }

        return {
            content: jsonContent,
            timeInfo
        };
    } catch (error) {
        if (error instanceof SyntaxError) {
            throw new Error('解密后的内容不是有效的 JSON 格式');
        }
        throw new Error(`${error instanceof Error ? error.message : String(error)}`);
    }
} 